/******************************************************************************* * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Felix Pahl (fpahl@web.de) - contributed fix for: * o introduce parameter throws NPE if there are compiler errors * (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=48325) *******************************************************************************/ package org.eclipse.jdt.internal.corext.refactoring.code; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.StringTokenizer; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.jface.text.TextSelection; import org.eclipse.ltk.core.refactoring.Change; import org.eclipse.ltk.core.refactoring.Refactoring; import org.eclipse.ltk.core.refactoring.RefactoringContribution; import org.eclipse.ltk.core.refactoring.RefactoringCore; import org.eclipse.ltk.core.refactoring.RefactoringStatus; import org.eclipse.ltk.core.refactoring.RefactoringStatusEntry; import org.eclipse.ltk.core.refactoring.participants.ProcessorBasedRefactoring; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.SourceRange; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.Annotation; import org.eclipse.jdt.core.dom.ArrayInitializer; import org.eclipse.jdt.core.dom.Assignment; import org.eclipse.jdt.core.dom.ClassInstanceCreation; import org.eclipse.jdt.core.dom.Expression; import org.eclipse.jdt.core.dom.FieldAccess; import org.eclipse.jdt.core.dom.IBinding; import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.MethodInvocation; import org.eclipse.jdt.core.dom.Name; import org.eclipse.jdt.core.dom.NodeFinder; import org.eclipse.jdt.core.dom.NullLiteral; import org.eclipse.jdt.core.dom.ParenthesizedExpression; import org.eclipse.jdt.core.dom.QualifiedName; import org.eclipse.jdt.core.dom.SimpleName; import org.eclipse.jdt.core.refactoring.IJavaRefactorings; import org.eclipse.jdt.core.refactoring.descriptors.ChangeMethodSignatureDescriptor; import org.eclipse.jdt.core.refactoring.descriptors.IntroduceParameterDescriptor; import org.eclipse.jdt.internal.core.refactoring.descriptors.RefactoringSignatureDescriptorFactory; import org.eclipse.jdt.internal.corext.Corext; import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility; import org.eclipse.jdt.internal.corext.dom.ASTNodes; import org.eclipse.jdt.internal.corext.dom.Bindings; import org.eclipse.jdt.internal.corext.dom.ScopeAnalyzer; import org.eclipse.jdt.internal.corext.dom.fragments.ASTFragmentFactory; import org.eclipse.jdt.internal.corext.dom.fragments.IASTFragment; import org.eclipse.jdt.internal.corext.dom.fragments.IExpressionFragment; import org.eclipse.jdt.internal.corext.refactoring.Checks; import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment; import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringArguments; import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringDescriptorUtil; import org.eclipse.jdt.internal.corext.refactoring.ParameterInfo; import org.eclipse.jdt.internal.corext.refactoring.RefactoringAvailabilityTester; import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages; import org.eclipse.jdt.internal.corext.refactoring.base.RefactoringStatusCodes; import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationRefactoringChange; import org.eclipse.jdt.internal.corext.refactoring.structure.BodyUpdater; import org.eclipse.jdt.internal.corext.refactoring.structure.ChangeSignatureProcessor; import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite; import org.eclipse.jdt.internal.corext.refactoring.tagging.IDelegateUpdating; import org.eclipse.jdt.internal.corext.util.Messages; import org.eclipse.jdt.ui.JavaElementLabels; import org.eclipse.jdt.internal.ui.JavaPlugin; import org.eclipse.jdt.internal.ui.actions.SelectionConverter; import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels; public class IntroduceParameterRefactoring extends Refactoring implements IDelegateUpdating { private static final String ATTRIBUTE_ARGUMENT= "argument"; //$NON-NLS-1$ private static final String[] KNOWN_METHOD_NAME_PREFIXES= {"get", "is"}; //$NON-NLS-2$ //$NON-NLS-1$ private ICompilationUnit fSourceCU; private int fSelectionStart; private int fSelectionLength; private IMethod fMethod; private Refactoring fChangeSignatureRefactoring; private ChangeSignatureProcessor fChangeSignatureProcessor; private ParameterInfo fParameter; private String fParameterName; private JavaRefactoringArguments fArguments; private Expression fSelectedExpression; private String[] fExcludedParameterNames; /** * Creates a new introduce parameter refactoring. * @param unit the compilation unit, or <code>null</code> if invoked by scripting * @param selectionStart start * @param selectionLength length */ public IntroduceParameterRefactoring(ICompilationUnit unit, int selectionStart, int selectionLength) { Assert.isTrue(selectionStart >= 0); Assert.isTrue(selectionLength >= 0); fSourceCU= unit; fSelectionStart= selectionStart; fSelectionLength= selectionLength; } public IntroduceParameterRefactoring(JavaRefactoringArguments arguments, RefactoringStatus status) { this(null, 0, 0); RefactoringStatus initializeStatus= initialize(arguments); status.merge(initializeStatus); } // ------------------- IDelegateUpdating ---------------------- public boolean canEnableDelegateUpdating() { return true; } public boolean getDelegateUpdating() { return (fChangeSignatureProcessor != null) ? fChangeSignatureProcessor.getDelegateUpdating() : false; } public void setDelegateUpdating(boolean updating) { if (fChangeSignatureProcessor != null) fChangeSignatureProcessor.setDelegateUpdating(updating); } public void setDeprecateDelegates(boolean deprecate) { if (fChangeSignatureProcessor != null) fChangeSignatureProcessor.setDeprecateDelegates(deprecate); } public boolean getDeprecateDelegates() { return (fChangeSignatureProcessor != null) ? fChangeSignatureProcessor.getDeprecateDelegates() : false; } // ------------------- /IDelegateUpdating --------------------- @Override public String getName() { return RefactoringCoreMessages.IntroduceParameterRefactoring_name; } //--- checkActivation @Override public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException { try { pm.beginTask("", 7); //$NON-NLS-1$ if (! fSourceCU.isStructureKnown()) return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.IntroduceParameterRefactoring_syntax_error); IJavaElement enclosingElement= SelectionConverter.resolveEnclosingElement(fSourceCU, new TextSelection(fSelectionStart, fSelectionLength)); if (! (enclosingElement instanceof IMethod)) return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.IntroduceParameterRefactoring_expression_in_method); fMethod= (IMethod) enclosingElement; pm.worked(1); RefactoringStatus result= new RefactoringStatus(); if (fArguments != null) { // invoked by script fChangeSignatureProcessor= new ChangeSignatureProcessor(fArguments, result); if (!result.hasFatalError()) { fChangeSignatureRefactoring= new ProcessorBasedRefactoring(fChangeSignatureProcessor); fChangeSignatureRefactoring.setValidationContext(getValidationContext()); result.merge(fChangeSignatureProcessor.checkInitialConditions(new SubProgressMonitor(pm, 2))); if (result.hasFatalError()) return result; } else { pm.worked(2); return result; } } else { // first try: fChangeSignatureProcessor= RefactoringAvailabilityTester.isChangeSignatureAvailable(fMethod) ? new ChangeSignatureProcessor(fMethod) : null; if (fChangeSignatureProcessor == null) return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.IntroduceParameterRefactoring_expression_in_method); fChangeSignatureRefactoring= new ProcessorBasedRefactoring(fChangeSignatureProcessor); fChangeSignatureRefactoring.setValidationContext(getValidationContext()); result.merge(fChangeSignatureProcessor.checkInitialConditions(new SubProgressMonitor(pm, 1))); if (result.hasFatalError()) { RefactoringStatusEntry entry= result.getEntryMatchingSeverity(RefactoringStatus.FATAL); if (entry.getCode() == RefactoringStatusCodes.OVERRIDES_ANOTHER_METHOD || entry.getCode() == RefactoringStatusCodes.METHOD_DECLARED_IN_INTERFACE) { // second try: IMethod method= (IMethod) entry.getData(); fChangeSignatureProcessor= RefactoringAvailabilityTester.isChangeSignatureAvailable(method) ? new ChangeSignatureProcessor(method) : null; if (fChangeSignatureProcessor == null) { String msg= Messages.format(RefactoringCoreMessages.IntroduceParameterRefactoring_cannot_introduce, entry.getMessage()); return RefactoringStatus.createFatalErrorStatus(msg); } result= fChangeSignatureProcessor.checkInitialConditions(new SubProgressMonitor(pm, 1)); if (result.hasFatalError()) return result; } else { return result; } } else { pm.worked(1); } } CompilationUnitRewrite cuRewrite= fChangeSignatureProcessor.getBaseCuRewrite(); if (! cuRewrite.getCu().equals(fSourceCU)) cuRewrite= new CompilationUnitRewrite(fSourceCU); // TODO: should try to avoid throwing away this AST initializeSelectedExpression(cuRewrite); pm.worked(1); result.merge(checkSelection(cuRewrite, new SubProgressMonitor(pm, 3))); if (result.hasFatalError()) return result; initializeExcludedParameterNames(cuRewrite); addParameterInfo(cuRewrite); fChangeSignatureProcessor.setBodyUpdater(new BodyUpdater() { @Override public void updateBody(MethodDeclaration methodDeclaration, CompilationUnitRewrite rewrite, RefactoringStatus updaterResult) { replaceSelectedExpression(rewrite); } }); return result; } finally { pm.done(); if (fChangeSignatureRefactoring != null) fChangeSignatureRefactoring.setValidationContext(null); } } private void addParameterInfo(CompilationUnitRewrite cuRewrite) throws JavaModelException { ITypeBinding typeBinding= Bindings.normalizeForDeclarationUse(fSelectedExpression.resolveTypeBinding(), fSelectedExpression.getAST()); String typeName= cuRewrite.getImportRewrite().addImport(typeBinding); String name= fParameterName != null ? fParameterName : guessedParameterName(); Expression expression= fSelectedExpression instanceof ParenthesizedExpression ? ((ParenthesizedExpression)fSelectedExpression).getExpression() : fSelectedExpression; String defaultValue= fSourceCU.getBuffer().getText(expression.getStartPosition(), expression.getLength()); fParameter= ParameterInfo.createInfoForAddedParameter(typeBinding, typeName, name, defaultValue); if (fArguments == null) { List<ParameterInfo> parameterInfos= fChangeSignatureProcessor.getParameterInfos(); int parametersCount= parameterInfos.size(); if (parametersCount > 0 && parameterInfos.get(parametersCount - 1).isOldVarargs()) parameterInfos.add(parametersCount - 1, fParameter); else parameterInfos.add(fParameter); } } private void replaceSelectedExpression(CompilationUnitRewrite cuRewrite) { if (! fSourceCU.equals(cuRewrite.getCu())) return; // TODO: do for all methodDeclarations and replace matching fragments? // cannot use fSelectedExpression here, since it could be from another AST (if method was replaced by overridden): Expression expression= (Expression) NodeFinder.perform(cuRewrite.getRoot(), fSelectedExpression.getStartPosition(), fSelectedExpression.getLength()); ASTNode newExpression= cuRewrite.getRoot().getAST().newSimpleName(fParameter.getNewName()); String description= RefactoringCoreMessages.IntroduceParameterRefactoring_replace; cuRewrite.getASTRewrite().replace(expression.getParent() instanceof ParenthesizedExpression ? expression.getParent() : expression, newExpression, cuRewrite.createGroupDescription(description)); } private void initializeSelectedExpression(CompilationUnitRewrite cuRewrite) throws JavaModelException { IASTFragment fragment= ASTFragmentFactory.createFragmentForSourceRange( new SourceRange(fSelectionStart, fSelectionLength), cuRewrite.getRoot(), cuRewrite.getCu()); if (! (fragment instanceof IExpressionFragment)) return; //TODO: doesn't handle selection of partial Expressions Expression expression= ((IExpressionFragment) fragment).getAssociatedExpression(); if (fragment.getStartPosition() != expression.getStartPosition() || fragment.getLength() != expression.getLength()) return; if (Checks.isInsideJavadoc(expression)) return; //TODO: exclude invalid selections if (Checks.isEnumCase(expression.getParent())) return; fSelectedExpression= expression; } private RefactoringStatus checkSelection(CompilationUnitRewrite cuRewrite, IProgressMonitor pm) { try { if (fSelectedExpression == null){ String message= RefactoringCoreMessages.IntroduceParameterRefactoring_select; return CodeRefactoringUtil.checkMethodSyntaxErrors(fSelectionStart, fSelectionLength, cuRewrite.getRoot(), message); } MethodDeclaration methodDeclaration= (MethodDeclaration) ASTNodes.getParent(fSelectedExpression, MethodDeclaration.class); if (methodDeclaration == null || ASTNodes.getParent(fSelectedExpression, Annotation.class) != null) return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.IntroduceParameterRefactoring_expression_in_method); if (methodDeclaration.resolveBinding() == null) return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.IntroduceParameterRefactoring_no_binding); //TODO: check for rippleMethods -> find matching fragments, consider callers of all rippleMethods RefactoringStatus result= new RefactoringStatus(); result.merge(checkExpression()); if (result.hasFatalError()) return result; result.merge(checkExpressionBinding()); if (result.hasFatalError()) return result; // if (isUsedInForInitializerOrUpdater(getSelectedExpression().getAssociatedExpression())) // return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.getString("ExtractTempRefactoring.for_initializer_updater")); //$NON-NLS-1$ // pm.worked(1); // // if (isReferringToLocalVariableFromFor(getSelectedExpression().getAssociatedExpression())) // return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.getString("ExtractTempRefactoring.refers_to_for_variable")); //$NON-NLS-1$ // pm.worked(1); return result; } finally { if (pm != null) pm.done(); } } private RefactoringStatus checkExpression() { //TODO: adjust error messages (or generalize for all refactorings on expression-selections?) Expression selectedExpression= fSelectedExpression; if (selectedExpression instanceof Name && selectedExpression.getParent() instanceof ClassInstanceCreation) return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_name_in_new); //TODO: let's just take the CIC automatically (no ambiguity -> no problem -> no dialog ;-) if (selectedExpression instanceof NullLiteral) { return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_null_literals); } else if (selectedExpression instanceof ArrayInitializer) { return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_array_initializer); } else if (selectedExpression instanceof Assignment) { if (selectedExpression.getParent() instanceof Expression) return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_assignment); else return null; } else if (selectedExpression instanceof SimpleName){ if ((((SimpleName)selectedExpression)).isDeclaration()) return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_names_in_declarations); if (selectedExpression.getParent() instanceof QualifiedName && selectedExpression.getLocationInParent() == QualifiedName.NAME_PROPERTY || selectedExpression.getParent() instanceof FieldAccess && selectedExpression.getLocationInParent() == FieldAccess.NAME_PROPERTY) return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_select_expression); } return null; } private RefactoringStatus checkExpressionBinding() { return checkExpressionFragmentIsRValue(); } // !! +/- same as in ExtractConstantRefactoring & ExtractTempRefactoring private RefactoringStatus checkExpressionFragmentIsRValue() { switch(Checks.checkExpressionIsRValue(fSelectedExpression)) { case Checks.IS_RVALUE_GUESSED: case Checks.NOT_RVALUE_MISC: return RefactoringStatus.createStatus(RefactoringStatus.FATAL, RefactoringCoreMessages.IntroduceParameterRefactoring_select, null, Corext.getPluginId(), RefactoringStatusCodes.EXPRESSION_NOT_RVALUE, null); case Checks.NOT_RVALUE_VOID: return RefactoringStatus.createStatus(RefactoringStatus.FATAL, RefactoringCoreMessages.IntroduceParameterRefactoring_no_void, null, Corext.getPluginId(), RefactoringStatusCodes.EXPRESSION_NOT_RVALUE_VOID, null); case Checks.IS_RVALUE: return new RefactoringStatus(); default: Assert.isTrue(false); return null; } } public List<ParameterInfo> getParameterInfos() { return fChangeSignatureProcessor.getParameterInfos(); } public ParameterInfo getAddedParameterInfo() { return fParameter; } public String getMethodSignaturePreview() throws JavaModelException { return fChangeSignatureProcessor.getNewMethodSignature(); } //--- Input setting/validation public void setParameterName(String name) { Assert.isNotNull(name); fParameter.setNewName(name); } /** * must only be called <i>after</i> checkActivation() * @return guessed parameter name */ public String guessedParameterName() { String[] proposals= guessParameterNames(); if (proposals.length == 0) return ""; //$NON-NLS-1$ else return proposals[0]; } // --- TODO: copied from ExtractTempRefactoring - should extract ------------------------------ /** * Must only be called <i>after</i> checkActivation(). * The first proposal should be used as "best guess" (if it exists). * @return proposed variable names (may be empty, but not null). */ public String[] guessParameterNames() { LinkedHashSet<String> proposals= new LinkedHashSet<String>(); //retain ordering, but prevent duplicates if (fSelectedExpression instanceof MethodInvocation){ proposals.addAll(guessTempNamesFromMethodInvocation((MethodInvocation) fSelectedExpression, fExcludedParameterNames)); } proposals.addAll(guessTempNamesFromExpression(fSelectedExpression, fExcludedParameterNames)); return proposals.toArray(new String[proposals.size()]); } private List<String> guessTempNamesFromMethodInvocation(MethodInvocation selectedMethodInvocation, String[] excludedVariableNames) { String methodName= selectedMethodInvocation.getName().getIdentifier(); for (int i= 0; i < KNOWN_METHOD_NAME_PREFIXES.length; i++) { String prefix= KNOWN_METHOD_NAME_PREFIXES[i]; if (! methodName.startsWith(prefix)) continue; //not this prefix if (methodName.length() == prefix.length()) return Collections.emptyList(); // prefix alone -> don't take method name char firstAfterPrefix= methodName.charAt(prefix.length()); if (! Character.isUpperCase(firstAfterPrefix)) continue; //not uppercase after prefix //found matching prefix String proposal= Character.toLowerCase(firstAfterPrefix) + methodName.substring(prefix.length() + 1); methodName= proposal; break; } String[] proposals= StubUtility.getLocalNameSuggestions(fSourceCU.getJavaProject(), methodName, 0, excludedVariableNames); return Arrays.asList(proposals); } private List<String> guessTempNamesFromExpression(Expression selectedExpression, String[] excluded) { ITypeBinding expressionBinding= Bindings.normalizeForDeclarationUse( selectedExpression.resolveTypeBinding(), selectedExpression.getAST()); String typeName= getQualifiedName(expressionBinding); if (typeName.length() == 0) typeName= expressionBinding.getName(); if (typeName.length() == 0) return Collections.emptyList(); int typeParamStart= typeName.indexOf("<"); //$NON-NLS-1$ if (typeParamStart != -1) typeName= typeName.substring(0, typeParamStart); String[] proposals= StubUtility.getLocalNameSuggestions(fSourceCU.getJavaProject(), typeName, expressionBinding.getDimensions(), excluded); return Arrays.asList(proposals); } // ---------------------------------------------------------------------- private static String getQualifiedName(ITypeBinding typeBinding) { if (typeBinding.isAnonymous()) return getQualifiedName(typeBinding.getSuperclass()); if (! typeBinding.isArray()) return typeBinding.getQualifiedName(); else return typeBinding.getElementType().getQualifiedName(); } private void initializeExcludedParameterNames(CompilationUnitRewrite cuRewrite) { IBinding[] bindings= new ScopeAnalyzer(cuRewrite.getRoot()).getDeclarationsInScope( fSelectedExpression.getStartPosition(), ScopeAnalyzer.VARIABLES); fExcludedParameterNames= new String[bindings.length]; for (int i= 0; i < fExcludedParameterNames.length; i++) { fExcludedParameterNames[i]= bindings[i].getName(); } } public RefactoringStatus validateInput() { return fChangeSignatureProcessor.checkSignature(); } //--- checkInput @Override public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException { fChangeSignatureRefactoring.setValidationContext(getValidationContext()); try { return fChangeSignatureRefactoring.checkFinalConditions(pm); } finally { fChangeSignatureRefactoring.setValidationContext(null); } } @Override public Change createChange(IProgressMonitor pm) throws CoreException { fChangeSignatureRefactoring.setValidationContext(getValidationContext()); try { Change[] changes= fChangeSignatureProcessor.getAllChanges(); return new DynamicValidationRefactoringChange(getRefactoringDescriptor(), RefactoringCoreMessages.IntroduceParameterRefactoring_name, changes); } finally { fChangeSignatureRefactoring.setValidationContext(null); pm.done(); } } private IntroduceParameterDescriptor getRefactoringDescriptor() { ChangeMethodSignatureDescriptor extended= (ChangeMethodSignatureDescriptor) fChangeSignatureProcessor.createDescriptor(); RefactoringContribution contribution= RefactoringCore.getRefactoringContribution(IJavaRefactorings.CHANGE_METHOD_SIGNATURE); Map<String, String> argumentsMap= contribution.retrieveArgumentMap(extended); final Map<String, String> arguments= new HashMap<String, String>(); arguments.put(ATTRIBUTE_ARGUMENT, fParameter.getNewName()); arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION, new Integer(fSelectionStart).toString() + " " + new Integer(fSelectionLength).toString()); //$NON-NLS-1$ arguments.putAll(argumentsMap); String signature= fChangeSignatureProcessor.getMethodName(); try { signature= fChangeSignatureProcessor.getOldMethodSignature(); } catch (JavaModelException exception) { JavaPlugin.log(exception); } final String description= Messages.format(RefactoringCoreMessages.IntroduceParameterRefactoring_descriptor_description_short, BasicElementLabels.getJavaElementName(fChangeSignatureProcessor.getMethod().getElementName())); final String header= Messages.format(RefactoringCoreMessages.IntroduceParameterRefactoring_descriptor_description, new String[] { BasicElementLabels.getJavaElementName(fParameter.getNewName()), signature, BasicElementLabels.getJavaCodeString(ASTNodes.asString(fSelectedExpression))}); final JDTRefactoringDescriptorComment comment= new JDTRefactoringDescriptorComment(extended.getProject(), this, header); comment.addSetting(Messages.format(RefactoringCoreMessages.IntroduceParameterRefactoring_original_pattern, JavaElementLabels.getTextLabel(fChangeSignatureProcessor.getMethod(), JavaElementLabels.ALL_FULLY_QUALIFIED))); comment.addSetting(Messages.format(RefactoringCoreMessages.IntroduceParameterRefactoring_expression_pattern, BasicElementLabels.getJavaCodeString(ASTNodes.asString(fSelectedExpression)))); comment.addSetting(Messages.format(RefactoringCoreMessages.IntroduceParameterRefactoring_parameter_pattern, BasicElementLabels.getJavaElementName(getAddedParameterInfo().getNewName()))); return RefactoringSignatureDescriptorFactory.createIntroduceParameterDescriptor(extended.getProject(), description, comment.asString(), arguments, extended.getFlags()); } private RefactoringStatus initialize(JavaRefactoringArguments arguments) { fArguments= arguments; final String selection= arguments.getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION); if (selection != null) { int offset= -1; int length= -1; final StringTokenizer tokenizer= new StringTokenizer(selection); if (tokenizer.hasMoreTokens()) offset= Integer.valueOf(tokenizer.nextToken()).intValue(); if (tokenizer.hasMoreTokens()) length= Integer.valueOf(tokenizer.nextToken()).intValue(); if (offset >= 0 && length >= 0) { fSelectionStart= offset; fSelectionLength= length; } else return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_illegal_argument, new Object[] { selection, JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION})); } else return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION)); final String handle= arguments.getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT); if (handle != null) { final IJavaElement element= JavaRefactoringDescriptorUtil.handleToElement(arguments.getProject(), handle, false); if (element == null || !element.exists() || element.getElementType() != IJavaElement.COMPILATION_UNIT) return JavaRefactoringDescriptorUtil.createInputFatalStatus(element, getName(), IJavaRefactorings.INTRODUCE_PARAMETER); else fSourceCU= (ICompilationUnit)element; } else return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT)); final String name= arguments.getAttribute(ATTRIBUTE_ARGUMENT); if (name != null && !"".equals(name)) //$NON-NLS-1$ fParameterName= name; else return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_ARGUMENT)); return new RefactoringStatus(); } /** * {@inheritDoc} */ public String getDelegateUpdatingTitle(boolean plural) { if (plural) return RefactoringCoreMessages.DelegateCreator_keep_original_changed_plural; else return RefactoringCoreMessages.DelegateCreator_keep_original_changed_singular; } }